<template>
  <div class="checkbox">
    <template v-if="enableCheckAll">
      <el-checkbox
        v-model="checkAll"
        :indeterminate="isIndeterminate"
        @change="handleCheckAllChange">
        全选
      </el-checkbox>
      <el-divider />
    </template>
    <el-checkbox-group
      v-model="checkedCities"
      @change="handleCheckedCitiesChange">
      <el-checkbox
        v-for="item in columns"
        :key="item[propsOptions.key]"
        :label="item[propsOptions.label]"
        :value="item[propsOptions.key]"></el-checkbox>
    </el-checkbox-group>
  </div>
</template>

<script lang="ts" setup>
import { PropType, ref, computed, watch } from 'vue'
import type { CheckboxValueType } from 'element-plus'

const props = defineProps({
  propsOptions: {
    type: Object as PropType<{ key: string; label: string }>,
    default: () => ({
      key: 'id',
      label: 'label'
    })
  },
  columns: {
    type: Array as PropType<Record<string, any>[]>,
    default: () => []
  },
  checkedList: {
    type: Array as PropType<string[] | number[]>,
    default: () => []
  },
  enableCheckAll: {
    type: Boolean,
    default: true
  }
})

const emits = defineEmits(['update:checkedList', 'change'])
const checkAll = ref<boolean>(false)
const isIndeterminate = ref<boolean>(false)
const citiesLen = ref<any[]>([])
const checkedCities = computed({
  get() {
    return props.checkedList
  },
  set(value) {
    emits('update:checkedList', value)
    emits('change', value)
  }
})

watch(
  () => props.columns,
  (newVal) => {
    citiesLen.value = newVal.map((item) => {
      return item.id
    })
    checkAll.value = checkedCities.value.length === citiesLen.value.length
    isIndeterminate.value = checkedCities.value.length > 0 && checkedCities.value.length < citiesLen.value.length
  },
  { immediate: true }
)

const handleCheckAllChange = (val: CheckboxValueType) => {
  checkedCities.value = val ? citiesLen.value : []
  isIndeterminate.value = false
}
const handleCheckedCitiesChange = (value: string[] | number[]) => {
  const checkedCount = value.length
  checkAll.value = checkedCount === citiesLen.value.length
  isIndeterminate.value = checkedCount > 0 && checkedCount < citiesLen.value.length
}
</script>

<style scoped lang="scss">
.checkbox {
  display: flex;
  width: 100%;
  display: flex;
  flex-direction: column;
  .el-divider {
    margin: 1px 0;
  }
  .el-checkbox-group {
    display: flex;
    flex-wrap: wrap;
  }
}
</style>
